package org.obsidianrad.server.services.user.ldap;


import java.sql.ResultSet;
import java.sql.SQLException;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.HashSet;
import java.util.List;
import java.util.Map;
import java.util.Set;

import javax.sql.DataSource;

import org.obsidianrad.server.services.user.rolemanager.RoleManager;
import org.springframework.jdbc.core.support.JdbcDaoSupport;
import org.springframework.jdbc.object.MappingSqlQuery;
import org.springframework.security.GrantedAuthority;
import org.springframework.security.GrantedAuthorityImpl;

public class JDBCGroupToRoleLoader extends JdbcDaoSupport implements GroupToRoleLoader {

	private static final String DEF_CONTEXT_LIST = "select class_name, perm_name, group_name from obs_perm";
	private Map<String, List<GrantedAuthority>> jdbcRoles;
	private ContextMapping contextMapping;
	private RoleManager roleManager;
	
	public JDBCGroupToRoleLoader(){
		this.jdbcRoles = new HashMap<String, List<GrantedAuthority>>();
	}
	
	@Override
	public Set<GrantedAuthority> loadRoles(Set<GrantedAuthority> groups) {
		Set<GrantedAuthority> returnValue = new HashSet<GrantedAuthority>();
		for(GrantedAuthority group: groups){
			if(jdbcRoles.containsKey(group.toString())){
				List<GrantedAuthority> listForGroup = jdbcRoles.get(group.toString());
				//retval.addAll(listForGroup);
				returnValue.addAll(listForGroup);				
			}
//			else if(group.toString().equals("ROLE_DOMAIN ADMINS")){
//				GrantedAuthority[] grantedAuthorities = roleManager.getGrantedAuthorities();
//				for(GrantedAuthority ga : grantedAuthorities){
//					returnValue.add(ga);
//				}
//			}
		}
		return returnValue;
	}


	@Override
	protected void initDao() throws Exception {
		super.initDao();
		this.contextMapping = new ContextMapping(getDataSource());
		contextMapping.execute();
	}

    /**
     * Query object to look up a user.
     */
	private class ContextMapping extends MappingSqlQuery {
		protected ContextMapping(DataSource ds) {
			super(ds, DEF_CONTEXT_LIST);
			compile();
		}

		protected Object mapRow(ResultSet rs, int rownum) throws SQLException {

			String group_name = "ROLE_" + rs.getString("group_name").toUpperCase();
			String class_name = rs.getString("class_name");
			String perm_name = rs.getString("perm_name");
			List<GrantedAuthority> list = jdbcRoles.get(group_name);
			if(list == null){
				list = new ArrayList<GrantedAuthority>();				
			}
			list.add( new GrantedAuthorityImpl(roleManager.constructRole(class_name, perm_name)) ); // TODO usare un rolemanager
			jdbcRoles.put(group_name, list);
			return null;
		}
	}

	public RoleManager getRoleManager() {
		return roleManager;
	}

	public void setRoleManager(RoleManager roleManager) {
		this.roleManager = roleManager;
	}
}
